// Copyright (c) 2011 Blue Onion Software, All rights reserved
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Web.UI;
using System.Xml;

namespace BlueOnionSoftware.Bloget
{
    internal class RssView : View
    {
        internal RssView(Bloget blogetArg)
            : base(blogetArg)
        {
        }

        protected override string RootClassId()
        {
            return null;
        }

        protected override void ShowView()
        {
            using (var writer = XmlRpc.CreateXmlWriter(Bloget.Page))
            {
                Rss20(writer);
            }

            Bloget.Page.Response.End();
        }


        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void Rss20(XmlWriter w)
        {
            if (w == null)
            {
                throw new ArgumentNullException("w");
            }
            w.WriteStartDocument();
            w.WriteStartElement("rss");
            w.WriteAttributeString("version", "2.0");

            w.WriteStartElement("channel");
            w.WriteElementString("title", Bloget.Blog.Title);
            w.WriteElementString("description", Bloget.Blog.Description);
            w.WriteElementString("link", Uri.EscapeUriString(Bloget.Blog.Link));
            w.WriteElementString("language", Bloget.Blog.Language);
            w.WriteElementString("copyright", Bloget.Blog.Copyright);
            w.WriteElementString("webMaster", Bloget.Blog.Webmaster);
            w.WriteElementString("generator", "Powered by Bloget");

            if (string.IsNullOrEmpty(Bloget.Blog.RssChannelImage) == false)
            {
                try
                {
                    w.WriteStartElement("image");
                    w.WriteElementString("url", Uri.EscapeUriString(Bloget.Blog.RssChannelImage));
                    w.WriteElementString("title", Bloget.Blog.Title);
                    w.WriteElementString("link", Uri.EscapeUriString(Bloget.Blog.Link));
                    w.WriteElementString("description", Bloget.Blog.Description);
                    w.WriteEndElement();
                }

                catch (Exception ex)
                {
                    Log.Exception(Bloget, "Rss20", ex);
                }
            }

            var count = 0;
            foreach (var post in 
                Bloget.Blog.EnumeratePosts(Bloget.QueryStart, Bloget.Blog.RssEntriesPerFeed, Bloget.QueryCategory, false, true))
            {
                w.WriteStartElement("item");
                w.WriteElementString("title", post.Title);
                w.WriteElementString("pubDate", post.Created.ToString("r", CultureInfo.InvariantCulture));
                w.WriteElementString("link", Uri.EscapeUriString(Bloget.PermaLink(post)));

                w.WriteStartElement("guid");
                w.WriteAttributeString("isPermaLink", "false");
                w.WriteString(post.Id.ToString());
                w.WriteEndElement();

                if (string.IsNullOrEmpty(Bloget.Blog.Webmaster) == false)
                {
                    w.WriteElementString("author", Bloget.Blog.Webmaster);
                }

                var content = Bloget.Blog.LoadContent(post.Id);

                if (Bloget.RssContentTemplate != null)
                {
                    var postContainer = new PostContainerControl(Bloget, Bloget.Blog, post, content);
                    Bloget.RssContentTemplate.InstantiateIn(postContainer);
                    postContainer.DataBind();

                    using (var sw = new StringWriter(CultureInfo.InvariantCulture))
                    {
                        using (var html = new HtmlTextWriter(sw))
                        {
                            html.BeginRender();
                            postContainer.RenderControl(html);
                            html.Flush();
                            html.EndRender();
                            w.WriteElementString("description", sw.ToString());
                        }
                    }
                }

                else
                {
                    w.WriteElementString("description", content.Text + Bloget.Blog.RssFooter);
                }

                foreach (var id in post.Tags)
                {
                    if (Bloget.Blog.Categories.Contains(id))
                    {
                        w.WriteElementString("category", Bloget.Blog.Categories[id].Name);
                    }
                }

                if (content.Attachments.Count > 0)
                {
                    var attachment = content.Attachments[0];
                    w.WriteStartElement("enclosure");
                    w.WriteAttributeString("url", Uri.EscapeUriString(attachment.Url));
                    w.WriteAttributeString("length", attachment.Length.ToString(CultureInfo.InvariantCulture));
                    w.WriteAttributeString("type", attachment.MimeType);
                    w.WriteEndElement();
                }

                w.WriteEndElement();

                if (++count >= Bloget.Blog.PostsPerPage)
                {
                    break;
                }
            }

            w.WriteEndDocument();
            w.Flush();
        }
    }
}